home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
boe.pres.k12.wv.us
/
boe.pres.k12.wv.us.zip
/
boe.pres.k12.wv.us
/
Utilities
/
Xerox Workcentre 5335
/
Windows Scan
/
32-bit_x86
/
Francais
/
cpsimage.cab
/
data
/
sys
/
vadof.elf
< prev
next >
Wrap
Text File
|
2009-03-16
|
21KB
|
582 lines
/* $Id: vadof.elf,v 1.15 2008/10/27 01:53:00 mfrey Exp $ */
/* vadof - Validate a Directory of Files
** This file contains a script used to validate a group of files in
** a given directory.
*/
#load "sys/stdio.elf";
#load "sys/datetime.elf";
#load "sys/xipxml.elf";
#load "sys/argTokenClass.elf";
/*****************************************************************************/
/* @VADOF */
/* @New VADOF - Validate a directory of files - This class is used to control
a workflow of file validation. The workflow will compare validation data
generated for files in a given directory against a master list of validations.
Construct a new instance with the name of the directory that has the files and
the name of the file that has the master list.
The results are:
A count of number fo files found not on the list and number of errors
A list of files found that are not one the list
A list of errors found
A new master list that would result in no errors.
*/
/* @diff Get difference data where success will be FALSE if there is a
processing error, errCnt will give the number of validation mis-matches,
and newCnt will provide the number of files in the directory that are not
in the current master list */
/* @logErrors Write the list of errors and new files to a text file. Will
return FALSE for any failure mode. */
/* @updateValidateFile Given the name of a file, a new XML file will be written
that contains the actual validation data for the given directory. */
/* @updateValidateXML Get the actual validation data for all of the files in
in the given dicrectory. The data is retuyrned in an XML DOM. */
/*****************************************************************************/
CLASS VADOF
{
METHOD New(STRING directory, STRING validation, LIST filters) {
this.fileDirectory = directory;
this.validFile = validation;
this.isProcessed = FALSE;
this.isValid = FALSE;
this.fileFilters = filters;
}
METHOD diff ( )
RETURNS (BOOLEAN success, INTEGER errCnt, INTEGER newCnt)
{
this.runProcess();
success = this.isValid;
if (success == TRUE) {
errCnt = this.invalExistingFiles.length()+this.missingFiles.length();
newCnt = this.filesWithoutVal.length();
} else {
errCnt = 0;
newCnt = 0;
}
}
METHOD logErrors(STRING filename) RETURNS (BOOLEAN success)
{
this.runProcess();
success = this.writeLog(filename: filename);
}
METHOD updateValidateFile(STRING filename) RETURNS (BOOLEAN success)
{
XmlDocument vaData = this.getNewValidate();
if (this.isValid == TRUE) {
vaData.dumpFile(filename: filename, format: 1);
success = TRUE;
} else {
success = FALSE;
}
}
METHOD updateValidateXML( ) RETURNS (XmlDocument vaData)
{
vaData = this.getNewValidate();
}
/*****************************************************************************
******************** Lots of Private Methods ******************************
*****************************************************************************/
private METHOD runProcess( )
{
if (this.isProcessed == TRUE) return;
this.isProcessed = TRUE;
this.prepareNodes();
if (this.isValid == FALSE) return;
this.prepareFiles();
if (this.isValid == FALSE) return;
this.runValidate();
}
private METHOD prepareNodes()
{
/* Test for filename (no name is okay), then make sure the
** given name is really a XML with correct root. Given a correct
** DOM, pass it to the parser */
if (this.validFile) {
XmlDocumentBuilder db;
XmlDocument vdoc = db.parseFile(filename: this.validFile);
if (!vdoc) {
this.isValid = FALSE;
return;
}
XmlNode root = vdoc.getDocumentElement();
STRING docname = root.getNodeName();
if (docname == "xipsValidation") {
this.ingestDOM(vdoc: vdoc);
} else {
this.isValid = FALSE;
return;
}
}
this.isValid = TRUE;
}
private METHOD prepareFiles()
{
FILE dirlst = new(FILE, path: this.fileDirectory);
if (!dirlst) {
this.isValid = FALSE;
return;
}
if (dirlst.isDirectory() == TRUE) {
this.fileList = dirlst.listFiles();
if(this.fileFilters){
this.trimList();
}
this.fileList.sort(lexical: 1, byname: 1);
}
this.isValid = TRUE;
}
private METHOD trimList()
{
LIST ltemp;
FILE ftemp;
INTEGER len = this.fileList.length();
INTEGER i ;
STRING stemp ;
for(i=0;i<len;i++){
ftemp = this.fileList.ref(entry: i);
stemp = ftemp.getExt();
if( this.fileFilters.search(name: stemp) != -1){
ltemp.insert(obj: ftemp, name: ftemp.getName());
}
}
this.fileList = ltemp;
}
private METHOD runValidate()
{
/* STEP 1: use the list of files to search the list of validation
** elements for matching names, test validation value, record results
** and remove the validation element */
if ((this.fileList) && (this.fileList.length() > 0)) {
if ((this.nodeList) && (this.nodeList.length() > 0)) {
this.fileProcWithList();
} else {
this.fileProcNoList();
}
}
/* STEP 2: If any validation elements remain, record them as errors */
if ((this.nodeList) && (this.nodeList.length() > 0)) {
INTEGER len = this.nodeList.length();
INTEGER i;
STRING fiName;
for (i=0; i<len; i++) {
fiName = this.nodeList.name(entry: i);
this.missingFiles.insert(name: fiName, obj: fiName);
}
this.nodeList.clear();
}
}
private METHOD fileProcNoList ()
{
FILE curFi;
INTEGER fiCnt = this.fileList.length();
INTEGER i;
STRING curName;
/* Just add them all to the "no data" list */
for (i=0; i<fiCnt; i++) {
curFi = this.fileList.ref(entry: i);
if (curFi.isFile() == TRUE) {
curName = curFi.getName();
this.filesWithoutVal.insert(name: curName,
obj: this.calcSum(src: curFi));
}
}
}
private METHOD fileProcWithList()
{
FILE curFi;
INTEGER fiCnt = this.fileList.length();
INTEGER i;
INTEGER ind;
STRING curName;
STRING oldMD;
STRING newMD;
for (i=0; i<fiCnt; i++) {
curFi = this.fileList.ref(entry: i);
if (curFi.isFile() == TRUE) {
curName = curFi.getName();
ind = this.nodeList.search(name: curName);
if (ind >= 0) {
oldMD = this.nodeList.extract(entry: ind);
newMD = this.calcSum(src: curFi);
if (oldMD == newMD) {
this.validExistingFiles.insert(name: curName, obj: oldMD);
} else {
this.invalExistingFiles.insert(name: curName, obj: newMD);
}
} else {
this.filesWithoutVal.insert(name: curName,
obj: this.calcSum(src: curFi));
} /* END else block of if ind >= 0 */
} /* END if isFile */
} /* END for fiCnt */
}
private METHOD calcSum (FILE src) RETURNS (STRING mdHash)
{
mdHash = MD5(filename: src.getCanonicalPath());
}
/****************************************************************************/
/************ private methods that: Output errors *************************/
/****************************************************************************/
private METHOD writeLog(STRING filename) RETURNS (BOOLEAN success)
{
/* TODO Add linefeeds & CRs to each write */
STRING lineBuf;
this.runProcess();
success = TRUE;
this.writeHeader(filename: filename);
if (this.isValid == FALSE) {
lineBuf = "Failed to process validation correctly\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
return;
}
this.writeError(filename: filename);
this.writeAbsent(filename: filename);
this.writeNewFiles(filename: filename);
}
private METHOD writeHeader(STRING filename)
{
DATETIME tm;
tm.setToCurrent(utc: FALSE);
STRING lineBuf = "This file generated by VADOF on " +
tm.toString()+"\n\n";
lineBuf.Write(filename: filename, value: 1);
}
private METHOD writeError(STRING filename)
{
STRING lineBuf;
INTEGER len;
if ((this.invalExistingFiles) && (this.invalExistingFiles.length() > 0)) {
len = this.invalExistingFiles.length();
INTEGER i;
lineBuf = "The following files had checksum errors \n\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
for (i=0; i<len; i++) {
lineBuf = " "+this.invalExistingFiles.name(entry:i)+"\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
}
} else {
lineBuf = "No checksum errors for existing files found\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
}
lineBuf = "\n\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
}
private METHOD writeAbsent(STRING filename)
{
STRING lineBuf;
INTEGER len;
if ((this.missingFiles) && (this.missingFiles.length() > 0)) {
len = this.missingFiles.length();
INTEGER i;
lineBuf = "The following files were missing \n\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
for (i=0; i<len; i++) {
lineBuf = " "+this.missingFiles.name(entry:i)+"\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
}
} else {
lineBuf = "No files were missing\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
}
lineBuf = "\n\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
}
private METHOD writeNewFiles(STRING filename)
{
STRING lineBuf;
INTEGER len;
if ((this.filesWithoutVal) && (this.filesWithoutVal.length() > 0)) {
len = this.filesWithoutVal.length();
INTEGER i;
lineBuf = "The following files were new \n\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
for (i=0; i<len; i++) {
lineBuf = " "+this.filesWithoutVal.name(entry:i)+"\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
}
} else {
lineBuf = "No new files found\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
}
lineBuf = "\n\n";
lineBuf.Write(filename: filename, value: 1, mode: "a");
lineBuf.Write(value: 1);
}
/****************************************************************************/
/************ private methods that: Ingest input XML **********************/
/****************************************************************************/
private METHOD ingestDOM(XmlDocument vdoc)
{
XPath xpath = vdoc.createXPath();
XmlNodeSet nset = xpath.evaluate(expr: "/xipsValidation/filelist");
if ((!nset) || (nset.getLength() < 1)) {
this.isValid = FALSE;
return;
}
nset = xpath.evaluate(expr: "/xipsValidation/filelist/file");
if ((!nset) || (nset.getLength() < 1)) {
/* Its a real DOM but no files are given...okay just let it go */
this.isValid = TRUE;
return;
}
INTEGER cnt = nset.getLength();
INTEGER i;
XmlElement fiElem;
for(i=0; i<cnt; i++) {
fiElem = nset.item(index:i);
if (this.addFileData(fiElem: fiElem) == FALSE) {
this.isValid = FALSE;
return;
}
}
this.isValid = TRUE;
}
private METHOD addFileData(XmlElement fiElem) RETURNS (BOOLEAN success)
{
STRING finm;
STRING fihs;
if (fiElem.hasAttribute(name: "name") == FALSE) {
success = FALSE;
return;
}
finm = fiElem.getAttribute(name: "name");
if (fiElem.hasAttribute(name: "hash") == FALSE) {
success = FALSE;
return;
}
fihs = fiElem.getAttribute(name: "hash");
this.nodeList.insert(name: finm, obj: fihs);
success = TRUE;
}
/****************************************************************************/
/************ private methods that: Build new XML *************************/
/****************************************************************************/
private METHOD getNewValidate ( ) RETURNS (XmlDocument vaData)
{
this.runProcess();
if (this.isValid == FALSE) return;
XmlDocumentBuilder xdb;
XmlDocument rtv = xdb.newDocument();
XmlElement root = rtv.createElement(name: "xipsValidation");
rtv.setDocumentElement(node: root);
XmlElement filelist = rtv.createElement(name: "filelist");
root.appendChild(node:filelist);
/*this.addFilesFromList(doc: rtv, fielem: filelist,
fiList: this.validExistingFiles);
this.addFilesFromList(doc: rtv, fielem: filelist,
fiList: this.filesWithoutVal);
this.addFilesFromList(doc: rtv, fielem: filelist,
fiList: this.invalExistingFiles);
*/
this.buildSortedList(vE: this.validExistingFiles, wV: this.filesWithoutVal,
iE: this.invalExistingFiles);
this.addFilesFromList(doc: rtv, fielem: filelist,
fiList: this.sortedFileList);
vaData = rtv;
}
private METHOD buildSortedList(LIST vE, LIST wV, LIST iE){
INTEGER i;
for(i=0;i<vE.length();i++){
this.sortedFileList.insert(name: vE.name(entry: i), obj: vE.ref(entry: i));
//print vE.name(entry: i); print vE.ref(entry: i);
}
for(i=0;i<wV.length();i++){
this.sortedFileList.insert(name: wV.name(entry: i), obj: wV.ref(entry: i));
}
for(i=0;i<iE.length();i++){
this.sortedFileList.insert(name: iE.name(entry: i), obj: iE.ref(entry: i));
}
this.sortedFileList.sort(lexical: 1, byname: 1);
}
private METHOD addFilesFromList(XmlDocument doc, XmlElement fielem, LIST fiList)
{
INTEGER len = fiList.length();
INTEGER i;
STRING fiName;
STRING fiHash;
XmlElement curElem;
for (i=0; i<len; i++) {
fiName = fiList.name(entry: i);
fiHash = fiList.ref(entry: i);
curElem = doc.createElement(name: "file");
curElem.setAttribute(value: fiName, name:"name");
curElem.setAttribute(value: fiHash, name:"hash");
fielem.appendChild(node: curElem);
}
}
/*****************************************************************************
******************** Internal Data Fields ******************************
*****************************************************************************/
BOOLEAN isValid;
BOOLEAN isProcessed;
STRING fileDirectory;
STRING validFile;
LIST fileList;
LIST fileFilters;
LIST nodeList;
LIST filesWithoutVal;
LIST invalExistingFiles;
LIST validExistingFiles;
LIST missingFiles;
LIST sortedFileList;
}
/************************************************************************************
************************** SCRIPTING TO USE CLASS *******************************
************************************************************************************/
/* @vadof
Validate a Directory of Files
// OVERVIEW
This utility can be used to create a master validation list from a directory of files
and later validate the same or similar directory of files for consistant checksums.
The utility requires only one parameter - the path to the directory. Script behavior
is dependent on the optional paramters.
// IMPORT PARAMETERS
STRING directory is the directory that contains the set of files.
STRING master (optional) Is the name of a file (xml) that contains the validation
list. If not provided, validation data will still be calculated for all files.
STRING errorLog (optional) If provided, this will be the name of a text file with
a list of files that failed to match the master, a list of files that were
missing from the directory based on the master list, and a list of new files.
BOOLEAN mkTDmaster (optional) When TRUE, a new master will be created based on the
existing directory of files. This may be done even when a master was given. The file
will be naed with a timestamp and placed in the current working directory.
STRING outputDir Prepend this path to the errorLog and the new validation master. Directory
will be created if it does not exist.
STRING flist Format "filters|ls|pdf,tif,...". When set the sciprt will only validate file with the given extensions. This is case insensitive.
*/
IMPORT STRING directory;
IMPORT STRING master;
IMPORT STRING errorLog;
IMPORT BOOLEAN mkTDmaster;
IMPORT STRING outputDir;
IMPORT STRING flist;
// Can be exported
BOOLEAN success = FALSE;
LIST filterList ;
INTEGER newFiles = 0;
INTEGER errorCnt = 0;
ARGTOKEN akf;
if (!directory) {
print "vadof: name of directory is required use directory:s pathname";
SetStatus(op: "stop", msg: "vadof: name of directry is required");
} else {
if (outputDir) {
FILE od = new(FILE, path: outputDir);
if (od.exists() == FALSE) {
od.mkdirs();
} else {
if (od.isDirectory() == FALSE) {
print "vadof: outputDir provided is not a directory";
SetStatus(op: "stop", msg: "vadof: outputDir provided is not a directory");
return;
}
}
}
if(flist){
akf= new(ARGTOKEN, param: flist);
filterList = akf.getValue();
INTEGER i, len = filterList.length();
LIST ltemp;
STRING stemp, upper, lower;
for(i=0;i<len;i++){
stemp = filterList.ref(entry: i);
upper = "."+stemp.toUpper();
lower = "."+stemp.toLower();
ltemp.insert(name: upper, obj: upper);
ltemp.insert(name: lower, obj: lower);
}
filterList = ltemp;
}
VADOF valObj = new(VADOF, directory: directory, validation: master, filters: filterList);
if (!valObj) return;
valObj.diff ( ) Returns (success: success, errCnt: errorCnt, newCnt: newFiles);
if (success == FALSE) {
print "vadof result: errors = "+errorCnt+" new files = "+newFiles;
SetStatus(op: "stop", msg: "VADOF: processing was unsuccessful");
return;
}
if (mkTDmaster == TRUE) {
STRING uniqFile;
DATETIME tm;
tm.setToCurrent(utc: FALSE);
uniqFile = "validate"+tm.toString()+".xml";
if (outputDir) {
uniqFile = outputDir+FILE.sep()+uniqFile;
}
success = valObj.updateValidateFile(filename: uniqFile);
if (success == FALSE) return;
}
if (errorLog) {
if (outputDir) {
errorLog = outputDir+FILE.sep()+errorLog;
}
success = valObj.logErrors(filename: errorLog);
}
print "vadof result: errors = "+errorCnt+" new files = "+newFiles;
if ((errorCnt != 0) || (newFiles != 0)) {
SetStatus(op: "stop", msg: "vadof: resulted in errors or new files");
}
}